/*************************************************************************
	> File Name: 028.HZOJ-636.旅行计划.cpp
	> Author: Maureen 
	> Mail: Maureen@qq.com 
	> Created Time: 一  6/28 15:35:59 2021
 ************************************************************************/

#include <iostream>
#include <queue>
#include <cstring>
#include <cstdio>
using namespace std;

struct edge {
    int e, next;
};

int n, m, head[100005], in_degree[100005], ans[100005]; //ans数组记录答案
edge edg[200005];

int main() {
    memset(head, -1, sizeof(head));
    cin >> n >> m;
    for (int i = 0; i < m; i++) {
        int x, y;
        cin >> x >> y;
        edg[i].e = y;
        edg[i].next = head[x];
        head[x] = i;
        in_degree[y]++;
    }

    queue<int> que;
    for (int i = 1; i <= n; i++) {
        if (in_degree[i] == 0) {
            que.push(i);
            ans[i] = 1;
        }
    }

    while (!que.empty()) {
        int t = que.front();
        que.pop();
        for (int i = head[t]; i != -1; i = edg[i].next) { //每次遍历一条边的时候，尝试更新终点的答案
            int e = edg[i].e;
            in_degree[e]--;
            ans[e] = max(ans[e], ans[t] + 1);
            if (in_degree[e] == 0) {
                que.push(e);
            }
        }
    }
    for (int i = 1; i <= n; i++) {
        //cout << ans[i] << endl;
        printf("%d\n", ans[i]);
    }

    return 0;
}
